package com.mryin.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ShearCaptcha;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mryin.common.ActiveUser;
import com.mryin.pojo.User;
import com.mryin.service.UserInfoService;
import com.mryin.service.UserService;
import com.mryin.util.ResultObj;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @program: MRYIN-ERP
 * @description:
 * @author: Mr.YIN
 * @create: 2021-02-25 16:51
 **/
@RequestMapping("/api/login")
@RestController
@Api(tags = "登录的一些接口")
public class LoginController {

    @Autowired
    private UserService userService ;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private StringRedisTemplate redisTemplate ;

    /*@RequestMapping("/doLogin")
    public String toLogin(){
        return "login";
    }*/

    /**
     * 用户登陆
     *
     * @param loginname 传递来的登陆名称
     * @param password  传递来打密码
     * @param keyCode   传递来的验证码名称 key
     * @param captcha   传递来的验证码
     * @return 返回登陆信息
     */
    @RequestMapping("doLogin")
    @ApiOperation("登录的接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "loginname" , value = "用户名"),
            @ApiImplicitParam(name = "password",value = "密码"),
            @ApiImplicitParam(name = "keyCode",value = "前端生成的随机4四位数，就是reids中存储的key"),
            @ApiImplicitParam(name = "captcha",value = "输入框输入的验证码"),
    })
    public ResultObj doLogin(String loginname, String password, String keyCode, String captcha) {
        // 获取redis验证码
        ValueOperations<String, String> forValue = redisTemplate.opsForValue();
        String code = forValue.get(keyCode);
        if (null == code) {
            return new ResultObj(-1, "当前验证码过期请重新获取");
        } else {
            try {
                System.out.println(captcha);
                // 进行比较 不考虑大小写
                if (code.equalsIgnoreCase(captcha)) {
                    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
                    User user = userService.getOne(queryWrapper.eq("username", loginname).eq("password", password));
                    // 获取主体
                    System.out.println(user);
                    Subject subject = SecurityUtils.getSubject();
                    System.out.println(subject);
                    // 认证
                    UsernamePasswordToken passwordToken = new UsernamePasswordToken(loginname, password);
                    System.out.println(passwordToken);
                    subject.login(passwordToken);
                     ActiveUser activeUser = (ActiveUser) subject.getPrincipal();
                    // 通过Shiro获取 Token   sessionid = token
                    String token = subject.getSession().getId().toString();
                    ///* 写入登陆日志开始 */
                    //Loginfo loginfo = new Loginfo();
                    //String remoteAddr = WebUtils.getHttpServletRequest().getRemoteAddr();
                    //ActiveUser active = (ActiveUser) subject.getPrincipal();
                    //loginfo.setLoginip(remoteAddr);
                    //loginfo.setLoginname(active.getUser().getName() + "-" + active.getUser().getLoginname());
                    //loginfo.setLogintime(new Date());
                    //loginfoService.save(loginfo);
                    /* 写入登陆日志结束 */
                    // 存储 前端登陆需要的信息
                    Map<String, Object> map = new HashMap<>();
                    map.put("token", token);
                    map.put("permissions", activeUser.getPermissions());
                    map.put("username", user.getUsername());
                    map.put("usertype", activeUser.getUser().getRoleId());
                    System.err.println("TOKEN:" + token);
                    //redisTemplate.opsForValue().set("Token",token,3600,TimeUnit.SECONDS);
                    //String token1 = redisTemplate.opsForValue().get("Token");
                    //System.out.println("我是从redis中取出来得==》"+token1);
                    return new ResultObj(200, "登陆成功", map);
                } else {
                    return new ResultObj(-1, "验证码错误");
                }
            } catch (Exception e) {
                e.printStackTrace();
                return new ResultObj(-1, "用户名或密码不正确");
            }


        }
    }





    /**
     * 验证是否登陆过
     *
     * @return
     */
    @RequestMapping("checkLogin")
    @ResponseBody
    public ResultObj checkLogin() {
        Subject subject = SecurityUtils.getSubject();
        // 判断是否认证成功
        boolean authenticated = subject.isAuthenticated();
        System.out.println(authenticated);
        if (subject.isAuthenticated()) {
            return ResultObj.IS_LOGIN;
        } else {
            return ResultObj.UN_LOGIN;
        }
    }

    /**
     * 返回验证码
     * 思路： 把验证码存入redis
     * 登陆时候 在进行获取出来 进行相应的判断
     * 接收的形式    key --- value
     *
     * @param response 返回出去的流
     * @param codeKey  接收验证码的key
     * @throws IOException
     */
    @RequestMapping("captcha")
    public void captcha(HttpServletResponse response, String codeKey) throws IOException {
        // 定义验证码
        ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(100, 38, 4, 2);
        String code = captcha.getCode();
        System.out.println(code);
        // 储存到redis
        ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
        opsForValue.set(codeKey, code);
        // 设置  缓存时间 60秒
        opsForValue.getOperations().expire(codeKey, 60, TimeUnit.SECONDS);
        // 返回流
        captcha.write(response.getOutputStream());
    }

    @RequestMapping("logout")
    @ResponseBody
    public ResultObj logout(HttpServletRequest request) {
        System.out.println("退出登录成功====>");
        // 清楚session
        HttpSession session = request.getSession();
        session.invalidate();
        // 退出认证
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        // 清理缓存
        String header = org.apache.shiro.web.util.WebUtils.toHttp(request).getHeader("TOKEN");
        System.out.println(header);
        //删除redis中的缓存token
        //redisTemplate.delete(header);
        // 删除redis缓存当中的  token
        redisTemplate.delete("Token");
        return new ResultObj(200, "success");
    }

}
